/* cSMWObject.h
 * SMW level object
 */
#ifndef __newmoon_csmwobject_h
#define __newmoon_csmwobject_h

class SMWObject;
#include <string.h> //memset
#include "mathx.h"
#include "uint.h"
#include "cLevel.h"
#include "cSNESPointer.h"
#include "smw.h"

class SMWObject {
	public:
		typedef enum {
			OBJ_NORMAL,		//Normal objects
			OBJ_EXTENDED,	//Extended objects except #0, #1
			OBJ_SCREEN_EXIT,//Extended object #0
			OBJ_SCREEN_JUMP,//Extended object #1
			OBJ_MAP16,		//Direct Map16 (NOT IMPLEMEMTED)
			NUM_OBJ_TYPES
		} SMWObjectType;
		
		static const u8 ObjectSet[NUM_TILESETS];
		static const u16 StdObjTiles[0x22];
		static const u16 TilesetObjTiles[5][16];
		static const u16 ExtObjMap16_2[0x4D];
		static u16 ExtObjMap16[0x32];
		static bool StaticInitialized;
		
		RawSMWObject Raw;
		u32 XPos, YPos; //Position within level; block coords
		u8 Width, Height;
		u32 MinWidth, MaxWidth, MinHeight, MaxHeight;
		bool Selected;
		SMWObjectType Type;
		u8 SubType; //e.g. which type of pipe, slope, etc
		u16 ObjID;
		u16 ScreenExitDest; //Destination level for screen exit objects.
		u8 NumBytes; //Number of bytes in the level data this object occupied,
		//when it was read from the ROM. This is NOT updated when the object is
		//changed; it's mainly just used to measure the level data size on load.
		
		SMWObject();
		SMWObject(SMWObjectType Type, u16 BlockNum); //TODO
		~SMWObject();
		bool Read(Level *Lv, ROMFile *File, u32 *Screen);
		void CalculateSize();
		bool Decode(Level *Lv, bool Layer2);
		bool IsVisible();
		bool GetHasSubType();
		u32 GetID(u8 Tileset);
		
	protected:
		bool HasSubType; //whether SubType is valid for this type
		
		void DecodeGroundEdge(Level *Lv, bool Layer2, s32 X1, s32 Y1, s32 X2, s32 Y2);
		void DecodeVerticalPipe(Level *Lv, bool Layer2, s32 X1, s32 Y1, s32 X2, s32 Y2);
		void DecodeHorizontalPipe(Level *Lv, bool Layer2, s32 X1, s32 Y1, s32 X2, s32 Y2);
		void DecodeSlope(Level *Lv, bool Layer2, s32 X1, s32 Y1, s32 X2, s32 Y2);
	
	private:
};
#endif //__newmoon_csmwobject_h
